package com.xuzmian.demo.java;

import java.util.ArrayList;
import java.util.List;

/**
 * java 形变
 *
 * @author xzm
 */
public class JavaGenerics {


    /**
     * 注释中如下代码是无法通过编译的，因为List<Number>和List<Integer>没有任何关系
     * List<Number> numbers = new ArrayList<Integer>(); //ERROR!
     */
    public static void successExample() {
        List<Number> numbers = new ArrayList<Number>();
        List<Integer> integers = new ArrayList<Integer>();

        numbers.add(1);
        /**
         * 下面这行代码没问题是因为addAll是这样定义的：boolean addAll(Collection<? extends E> c);
         * "? extends E" 其实就是使用点协变，允许传入的参数可以是泛型参数类型为Number 子类的任意类型。
         * 也有"? super E"的用法，这表示元素类型为E 及其父类，这个通常也叫作逆变。
         */
        numbers.addAll(integers);
    }


    public static void errorExample() {
        Parent parent = new Parent();
        List<Clild> clilds = new ArrayList<Clild>();
        /**
         * 注释中这行代码不能通过编译，因为没使用addAll 方法入参的型参没有定义"? extends E"，即可在使用点协变。
         * parent.addAll(clilds);
         */
        parent.copyAll(clilds);
    }

}

class Parent {
    public boolean addAll(List<Parent> list) {
        return true;
    }

    public boolean copyAll(List<? extends Parent> list) {
        return true;
    }
}

class Clild extends Parent {
}